﻿using System.Globalization;
using FamaWebSite.Models;
using FamaWebSite.Notifiers;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading;
using System.Web.Mvc;

namespace FamaWebSite.Controllers
{
    public class MaisProvavelController : Controller
    {
        private List<string> list;

        public MaisProvavelController()
        {
            string path = @"C:\Users\Joilson\Desktop\FAMA\trunk\inputs\uploads";
            string[] files = Directory.GetFiles(path);
            list = files.Select(selector: Path.GetFileName).ToList();
        }

        #region private properties
        private const string MAIS_PROVAVEL = "MaisProvavel";
        private const string REGRESSAO_LINEAR = "RegressaoLinear";
        #endregion

        #region Imported Methods

        [DllImport(@"C:\Users\Joilson\Documents\Visual Studio 2012\Projects\CppFamaDLL\Debug\CppFamaDLL.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern float executarMaisProvavel(ParametrosMaisProvavel parm);

        [DllImport(@"C:\Users\Joilson\Documents\Visual Studio 2012\Projects\CppFamaDLL\Debug\CppFamaDLL.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern string validarMaisProvavel(ParametrosMaisProvavel parm);

        #endregion

        //
        // GET: /MaisProvavel/
        public ActionResult Index()
        {
            return View();
        }

        //
        // GET: /MaisProvavel/Execute
        public ActionResult Execute()
        {
            return View(new ParametrosModel { FilesList = list });
        }

        [HttpPost]
        public ActionResult Execute(string algoritmo)
        {
            return View(new ParametrosModel { FilesList = list, Algoritmo = algoritmo });
        }

        static void ThreadProc(Object stateInfo)
        {
            var model = (ParametrosModel)stateInfo;
            var parm = (ParametrosMaisProvavel)model;
            float result = 0;

            switch (model.Algoritmo)
            {
                case MAIS_PROVAVEL:
                    result = executarMaisProvavel(parm);
                    break;
                case REGRESSAO_LINEAR:
                    throw new NotImplementedException();
            }

            string path = @"C:\Users\Joilson\Desktop\FAMA\trunk\Joilson\result.txt";
            System.IO.File.WriteAllText(path, result.ToString());
        }

        [HttpPost]
        public ActionResult Classificar(ParametrosModel model)
        {
            IUserNotifier _notifier = new UserNotifier();

            if (ModelState.IsValid && !String.IsNullOrEmpty(model.Email))
            {
                // chama o notificar do antes de mandar executar o metodo
                _notifier.SendNotification(model.Email);

                if (ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadProc), model))
                {
                    //TODO: Transferir todas as strings para um arquivo de resources
                    ViewBag.OperationResult =
                        "Sua requisição foi enfileirada com sucesso! Você receberá um e-mail com os resultados.";
                    ViewBag.wasSent = true;
                }
                else
                {
                    //TODO: Transferir todas as strings para um arquivo de resources
                    ViewBag.OperationResult = "Sua requisição não pôde ser enfileirada!";
                    ViewBag.wasSent = false;
                }

                return View("Index", model);
            }

            model.FilesList = list;
            return View("Execute", model);
        }

        [HttpPost]
        public ActionResult Validar(ParametrosModel model)
        {
            if (model.PorcentagemDeDivisao != null)
                model.PorcentagemDeDivisaoFloat = float.Parse(model.PorcentagemDeDivisao) / 100;

            var resultado = ExecutarValidacao(model);
            model.Resposta = resultado.Split(',').Select(c => float.Parse(c, CultureInfo.CreateSpecificCulture("en-US")) * 100).ToList();
            model.FilesList = list;

            return View("Execute", model);
        }

        private static string ExecutarValidacao(ParametrosModel model)
        {
            string resultado = null;

            switch (model.Algoritmo)
            {
                case MAIS_PROVAVEL:
                    resultado = validarMaisProvavel((ParametrosMaisProvavel)model); break;
                case REGRESSAO_LINEAR:
                    throw new NotImplementedException();
            }

            return resultado;
        }
    }
}
